import { _cos, _sin, _k, _move, _o, _mid, _lerp } from "../math/index.js";
import { _traversal } from "./traversal.js";
/*绘制谢尔宾斯基三角形的方法
  p：正三角形中心点坐标，r:顶点到中心点距离，depth：递归深度*/
export const sierpinskiTrianglePoints = ({ o, r, depth, a = 0, k = 1 }) => {
    //  三角形边长
    let len = r * Math.sqrt(3)
    //记录当前端点，默认为左下角顶点坐标
    let currentPoint = [o[0] - len / 2, o[1] + r / 2]
    //记录当前方向角
    var currentAngle = a;

    //旋转方法，将下次画线的方向逆时针旋转
    function turn(angle) {
        currentAngle += angle;
    }

    //开始画折线，如果深度是偶数便可直接绘制折线，否则需要以斜60度为初始方向
    let points = [currentPoint]



    const _iter = (depth, length, angle) => {
        if (depth === 0) {
            currentPoint = _move(currentPoint, [0, 0], [_k(length * _cos(currentAngle)), -k * _k(length * _sin(currentAngle))])
            points.push(currentPoint)
        } else {
            //递归画三段折线
            _iter(depth - 1, length / 2, -angle);
            turn(angle);
            _iter(depth - 1, length / 2, angle);
            turn(angle);
            _iter(depth - 1, length / 2, -angle);
        }
    }
    if (depth % 2 == 0) {
        _iter(depth, len, -60);
    } else {
        turn(60);
        _iter(depth, len, -60);
    }
    return points
}

export const bottomControlGearTypes = ['bottom', 'middle', 'top']


// 顶部控制点
const _topControl = ([from, to], o, amplitude) => {
    let o1 = _o([from, to])
    return amplitude ? _lerp(o1, o, amplitude) : o1
}

// 底部控制点
const _bottomControl = ([from, c1, c2, to], bottomControlGear) => {
    let ps
    switch (bottomControlGear) {
        case 'bottom':
            ps = [from, to]
            break
        case 'middle':
            ps = [from, c1, c2, to]
            break
        case 'top':
            ps = [c1, c2]
            break
        default:
            ps = [from, c1, c2, to]
    }
    return _o(ps)
}

const _sierpinski = ([from, to], o, depth, bottomControlGear, amplitude) => {
    let o1 = _topControl([from, to], o, amplitude)
    let c1 = _mid(from, o1)
    let c2 = _mid(to, o1)
    if (depth === 0) {
        return [from]
    }
    else if (depth === 1) {
        return [from, c1, c2]
    } else {
        let o2 = _bottomControl([from, c1, c2, to], bottomControlGear, amplitude)
        depth -= 1
        let ps = []
        ps.push(..._sierpinski([from, c1], o2, depth, bottomControlGear, amplitude))
        ps.push(..._sierpinski([c1, c2], o1, depth, bottomControlGear, amplitude))
        ps.push(..._sierpinski([c2, to], o2, depth, bottomControlGear, amplitude))
        return ps
    }
}


// 边与中心点 组成一个三角形
export const sierpinskiPoints = ({ points, depth = 0, loop = false, bottomControlGear, amplitude, discrete }) => {
    let o = _o(points)
    let result = []
    let iter = ([t, next]) => {
        let ps = _sierpinski([t, next], o, depth, bottomControlGear, amplitude)
        result.push(...ps)
    }
    let n = 2
    _traversal({ points, n, loop, iter, discrete })
    return result
}



export const sierpinski3Points = ({ points, depth = 0, loop = false }) => {
    let result = []

    let iter = ([p1, p2, p3]) => {
        let ps = _sierpinski([p1, p2], p3, depth, 'bottom')
        result.push(...ps)
    }
    let n = 4
    _traversal({ points, loop, n, iter })
    return result
}


